<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        var a = [];
        var b = {};
        console.log(a)
        console.log(b)
        // 1
        // 构造器
        console.log(a.constructor)  // ƒ Array() { [native code] }
        console.log(b.constructor)  // ƒ Object() { [native code] }
        console.log(a.constructor === Array)  // true
        console.log(b.constructor === Array)  // false
        console.log(a.constructor === Object)  // false
        console.log(b.constructor === Object)  // true

        // 2
        // instanceof 运算符可以用来判断某个构造函数的prototype属性所指向的对象是否存在于另外一个要检测对象的原型链上
        // 因为Object在原型链的上层，所以都会返回true
        console.log(a instanceof Array)   // true
        console.log(b instanceof Array)   // false
        console.log(a instanceof Object)  // true
        console.log(b instanceof Object)  // true

        console.log([] instanceof Array)  // true
        console.log([] instanceof Object) // true
        console.log({} instanceof Array)  // false
        console.log({} instanceof Object) // true

        // 3
        // 每一个对象都有__proto__属性，指向创建该对象的构造函数的原型
        console.log(a.__proto__ === Array.prototype)  // true
        // 返回指定对象的原型
        console.log(Object.getPrototypeOf(a) === Array.prototype) // true
        // 通过Array原型链上的isPrototypeOf 该方法用于测试一个对象是否在另一个对象的原型链上
        console.log(Array.prototype.isPrototypeOf(a)) // true
        console.log(Array.prototype.isPrototypeOf(b)) // false

        // 以上三种是通过原型来判断的
           
        // 4
        // toString 是原型链顶端的一个方法，然后改变this指向a,相当于如下
        
        // Object.prototype = {
        //     toString: function() {
        //         a.toString();
        //     }
        // }

        var str = Object.prototype.toString.call(a);
        console.log(str);                   // [object Array]tips
        var tips = '[object Array]';        // 缓存优化
        if( str === tips ) {
            console.log('数组')
        }else {
            console.log('非数组')
        }                                   // 数组

        var str2 = Object.prototype.toString.call(b);
        console.log(str2);                  // [object Array]
        var tips = '[object Array]';        // 缓存优化
        if( str2 === tips ) {
            console.log('数组')
        }else {
            console.log('非数组')
        }                                   // 非数组

        // 5
        // ES6新增方法
        console.log(Array.isArray(a)) // true
        console.log(Array.isArray(b)) // false
    </script>
</body>
</html>